<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            margin-top: 20px;
            width: 1000px;
            margin: 0 auto;
        }

        .header {
            height: 200px;
            background-color: blue;
        }

        .body {
            height: 800px;
            background-color: brown;
        }

        .footer {
            height: 900px;
            background-color: burlywood;
        }

        .side {
            position: absolute;
            top: 300px;
            right: 50px;
            width: 50px;
            height: 200px;
            background-color: skyblue;
        }

        span {
            display: none;
        }
    </style>
</head>

<body>
    <div class="header">

    </div>
    <div class="body">

    </div>
    <div class="footer">

    </div>
    <!-- 侧边栏 -->
    <div class="side">
        <span>返回顶部</span>
    </div>

    <script>
        var side = document.querySelector('.side');
        var body = document.querySelector('.body');
        var footer = document.querySelector('.footer');
        var back = document.querySelector('span');
        var bodyTop = body.offsetTop;
        var sideTop = side.offsetTop - bodyTop;
        var footerTop = footer.offsetTop;
        //滚动事件
        window.addEventListener('scroll', function () {
            // window.pageYOffset 用于页面被减去的头部
            if (window.pageYOffset >= bodyTop) {
                side.style.position = 'fixed';
                side.style.top = sideTop + 'px';
            } else {
                side.style.position = 'absolute';
                side.style.top = 300 + 'px';
            }

            if (window.pageYOffset >= footerTop) {
                back.style.display = 'block';
            } else {
                back.style.display = 'none';
            }
            //点击返回顶部效果
            back.addEventListener('click', function () {
                // window.scroll(0, 0);
                animate(window, 0);
            })
        });


        function animate(obj, target, callback) {
            //先清除一次定时器
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                //缓动动画公式   （目标距离 - 现在距离）/ 10
                // var step = (target - obj.offsetLeft) / 10;
                //js中要避免出现小数情况，需要取整
                // var step = Math.ceil((target - obj.offsetLeft) / 10);
                //可是，考虑到退回来出现负数的情况，取整情况有两种
                var step = (target - window.pageYOffset) / 10;
                step = step > 0 ? Math.ceil((target - window.pageYOffset) / 10) : Math.floor((target - window.pageYOffset) / 10);
                //判断动画停止条件
                if (window.pageYOffset == target) {
                    clearInterval(obj.timer);
                    //回调函数写在定时器结束之后
                    //先判断有没有回调函数，如果有回调函数，则运行回调函数
                    if (callback) {
                        callback();
                    }
                }
                // obj.style.left = window.pageYOffset + step + 'px';
                window.scroll(0, window.pageYOffset + step);
            }, 10)
        }
    </script>
</body>

</html>